package com.hrms.hrms_employee.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hrms.common.utils.DateUtil;
import com.hrms.common.utils.RedisUtil;
import com.hrms.common.vo.ResultMessage;
import com.hrms.hrms_employee.dao.DepartmentDao;
import com.hrms.hrms_employee.dao.StationDao;
import com.hrms.hrms_employee.dto.*;
import com.hrms.hrms_employee.entity.Department;
import com.hrms.hrms_employee.entity.Station;
import com.hrms.hrms_employee.service.DepartmentService;
import com.hrms.hrms_employee.service.StationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.sql.Date;
import java.time.LocalDate;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 部门表(Department)表服务实现类
 *
 * @author makejava
 * @since 2025-01-14 16:22:17
 */
@Service("departmentService")
public class DepartmentServiceImpl extends ServiceImpl<DepartmentDao, Department> implements DepartmentService {

    @Autowired
    private StationService stationService;
    @Autowired
    private StationDao stationDao;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<Department> selectDepartmentTree()  {
        /**
         * 查出所有分类，组装成树形结构
         * 查出所有子分类
         *    查询所有的一级分类
         */
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        if (redisUtil.hasKey("department")) {
            List<Department> resultList = JSON.parseArray(redisUtil.get("department"), Department.class);
            return resultList;
        }
        List<Department> entities = baseMapper.selectList(new QueryWrapper<Department>().eq("is_deleted",0));
        List<Station> stations = this.stationService.getBaseMapper().selectList(null);
        List<Department> menus = entities.stream().filter((department) -> {
            return department.getParentId() == 0;
        }).map((menu)->{
                menu.setChildren(getchildren(menu,entities,stations));
//                menu.setStation(getStation(menu,stations));
            return menu;
        }).collect(Collectors.toList());
        String jsonString = JSON.toJSON(menus).toString();
        redisUtil.setEx("department", jsonString,1, TimeUnit.DAYS);
        return menus;
    }

    @Override
    public void saveInfo(Department department) {
//        JobNumber jobNumber = jobNumberService.getBaseMapper().selectOne(new QueryWrapper<JobNumber>().eq("type", JobNumberInfo.IT.getType()));
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        redisUtil.delete("department");
        this.saveOrUpdate(department);
    }

    /**
     * 级联删除部门及其子部门和岗位
     * @param id
     */
    @Override
    public void removeByInfo(Long id) {
        this.update(new UpdateWrapper<Department>().eq("id",id).set("is_deleted",1));
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        redisUtil.delete("department");
    }

    /**
     * 根据departmentId查询所有子部门及其岗位
     * @param departmentId
     * @return
     */
    @Override
    public List<Department> selectByDepartmentId(Long departmentId) {
        List<Department> entities = baseMapper.selectList(new QueryWrapper<Department>().eq("is_deleted",0));
        List<Station> stations = this.stationService.getBaseMapper().selectList(null);
        List<Department> menus = entities.stream().filter((department) -> {
            return department.getCode().equals(departmentId);
        }).map((menu)->{
            menu.setChildren(getchildren(menu,entities,stations));
            menu.setStation(getStation(menu,stations));
            return menu;
        }).collect(Collectors.toList());
        return menus;
    }

    /**
     * 获取部门人数
     * @return
     */

    @Override
    public ResultMessage getDepartmentEmployee() {
        List<Department> departments = this.selectDepartmentTree();
        List<DepartmentStatDTO> dtos = new ArrayList<>();
        departments.stream().forEach(department -> {
            department.getChildren().stream().forEach(department1 -> {
                AtomicInteger atomicNumber = new AtomicInteger(0);
                Integer employeeNumber = this.getchildEmployee(department1, atomicNumber);
                DepartmentStatDTO dto = new DepartmentStatDTO();
                dto.setDepartment(department1.getName());
                dto.setEmployeeCount(employeeNumber);
                dtos.add(dto);
            });
        });

        return new ResultMessage(ResultMessage.Success,"",dtos);
    }

    /**
     * 员工异动
     * @return
     */
    @Override
    public ResultMessage getEmployeeChange(String yearMonth) {
        YearMonth month = YearMonth.parse(yearMonth);
        DateUtil dateUtil = new DateUtil();
        LocalDate preMonthFirst = dateUtil.getMonthFirst(month);
        LocalDate preMonthLast = dateUtil.getMonthLast(month);
        List<EmployeeChangeDTO> dtos = this.stationDao.emoloyeeChange(preMonthFirst,preMonthLast);
        if (dtos!=null) {
            dtos.stream().forEach(employeeChangeDTO -> {
                employeeChangeDTO.setYearMonth(yearMonth);
            });
        }
        return new ResultMessage(ResultMessage.Success,"",dtos);
    }

    /**
     * 年龄分布
     * @return
     */
    @Override
    public ResultMessage getEmployeeAge() {
        List<AgeRangeStatDTO> dtos = this.stationDao.getEmployeeAge();
        return new ResultMessage(ResultMessage.Success,"",dtos);
    }

    /**
     * 学历分布
     * @return
     */
    @Override
    public ResultMessage getEmployeeEducation() {
        List<EducationDTO> dtos = this.stationDao.getEmployeeEducation();
        return new ResultMessage(ResultMessage.Success,"",dtos);
    }

    /**
     * 工作年龄分布
     * @return
     */
    @Override
    public ResultMessage getEmployeeWorkDate() {
        List<WorkDTO> dtos = this.stationDao.getEmployeeWorkDate();
        return new ResultMessage(ResultMessage.Success,"",dtos);
    }

    @Override
    public ResultMessage getEmployeeContractType() {
        List<ContractTypeDTO> dtos = this.stationDao.getEmployeeContractType();
        return new ResultMessage(ResultMessage.Success,"",dtos);
    }

    /**
     * 岗位人数分布
     * @return
     */
    @Override
    public ResultMessage getStationEmployee() {
        List<StationDTO> dtos = this.stationDao.getStationEmployee();
        return new ResultMessage(ResultMessage.Success,"",dtos);
    }


    /**
     * 获取子部门员工数量
     *
     * @param
     * @param department
     * @param atomicNumber
     */
    private Integer getchildEmployee(Department department, AtomicInteger atomicNumber) {
        if(department.getChildren() != null) {
            department.getChildren().stream().forEach(department1 -> {
                this.getchildEmployee(department1, atomicNumber);
            });
        }
        if (department.getStation() != null) {
            department.getStation().stream().forEach(station -> {
                //统计员工数量
                Integer number = this.stationService.seelectEmployee(station.getName());
                atomicNumber.addAndGet(number);
            });
        }
        return atomicNumber.get();
    }

    private List<Station> getStation(Department menu, List<Station> stations) {
        List<Station> stationList = stations.stream().filter(station -> {
            return station.getDepartmentId().equals(menu.getCode());
        }).collect(Collectors.toList());
        return stationList;
    }

    private List<Department> getchildren(Department menu, List<Department> entities, List<Station> stations) {
        List<Department> collect = entities.stream().filter(department -> {
            return department.getParentId().equals(menu.getCode());
        }).map(childs -> {
            childs.setChildren(getchildren(childs, entities, stations));
            childs.setStation(getStation(childs,stations));
            return childs;
        }).collect(Collectors.toList());
        return collect;
    }
}

